﻿#ifndef _MAPMANAGER_H_INCLUDE_
#define _MAPMANAGER_H_INCLUDE_

#include <QObject>
#include <QList>
#include <QHash>
#include <QTimer>

#include "common.h"
#include "rolemanager.h"
#include "common/singleton.h"
#include "network/cwebsocketserver.h"
#include "network/networkframemanager.h"
#include "network/chttpserver.h"
#include "dboperator.h"

class BaseMap;

class MapManager : public CWebSocketServer,public NetworkFrameManager,public Singleton<MapManager>
{
    Q_OBJECT

public:
    explicit MapManager(QObject *parent=nullptr);
    ~MapManager();

    /// 从XML中导入地图信息
    bool loadMapFromXML(QString filepath);
    /// 从XML中导入怪物配置
    bool loadMonsterFromXML(QString filepath);
    /// 从XML中导入弹药信息
    bool loadBulletFromXML(QString filepath);
    /// 从XML中导入用户等级信息
    bool loadGradeFromXML(QString filepath);
    /// 从ini中导入系统配置
    void loadSystemConfigFromINI(QString filepath);
    /// 启动服务器
    void startServer(void);

    /// 添加一个地图到管理器中
    bool addMap(BaseMap *map);
    /// 检测指定地图是否存在
    bool isExistMap(BaseMap *map);
    /// 清除所有的地图
    void deleteMapList(void);
    /// 得到地图列表
    inline QHash<int,BaseMap*>& getBaseMapList(void) { return mBaseMapList; }
    /// 得到指定ID的地图
    BaseMap* getMapById(int id);
    /// 设置http服务器端口
    inline void setHttpServerPort(int port) { nHttpServerPort = port; }
    /// 得到http服务器端口
    inline int getHttpServerPort(void) { return nHttpServerPort; }
    /// 设置http服务器IP
    inline void setHttpServerIP(QString ip) { mHttpServerIP = ip; }
    /// 得到http服务器IP
    inline QString getHttpServerIP(void) { return mHttpServerIP; }
    /// 设置侦听端口
    inline void setListenPort(int port) { mListenPort = port; }
    /// 得到侦听端口
    inline int getListenPort(void) { return mListenPort; }
    /// 设置角色可视的范围
    inline void setViewSize(QSize size) { mViewSize = size; }
    /// 得到角色可视的范围
    inline QSize getViewSize(void) { return mViewSize; }
    /// 设置项目名称
    inline void setProName(QString name) { mProName = name; }
    /// 得到项目名称
    inline QString getProName(void) { return mProName; }
    /// 得到弹药信息
    inline QHash<int,tagBulletInfo*>& getBulletInfos(void) { return mBulletInfoList; }
    /// 得到指定ID的弹药信息
    tagBulletInfo* getBulletInfo(int id);
    /// 清除所有的弹药信息
    void clearAllBulletInfos(void);
    /// 得到指定经验值的等级信息
    tagGradeInfo* getGradeInfoByExperience(int experience);
    /// 得到所有的等级信息
    QMap<int,tagGradeInfo>& getAllGradeInfo(void) { return mGradeInfoList; }
    /// 发送指定的公告给客户端
    void sendNotice(BaseRole *role,QString type,QString message);

    /// 更新角色地图信息
    void updateRoleMap(BaseRole *role);
    /// 删除指定的角色
    void deleteRoleFromMap(BaseRole *role);
    /// 发送消息给当前角色可见的所有其它角色
    void sendViewRoles(BaseRole * role,QString msg);
    /// 更新指定角色的游戏信息
    void updateRoleGameInfo(BaseRole *role);

    /// 处理http请求
    virtual bool OnProcessHttpAccepted(QObject *obj,const QPointer< JQHttpServer::Session > &session);

private slots:
    /// 处理网络字符串消息
    void slots_signalsNetText(QWebSocket *conn,QString mes);
    /// 处理一个新的连接到达
    void slots_signalsConnectedNetMes(QWebSocket *conn);
    /// 处理一个连接关闭
    void slots_signalsDisconnectedNetMes(QWebSocket *conn);
    /// 更新
    void update(void);

private:
    /// 发送添加角色消息
    void sendAddRoleMsg(BaseRole *role);
    /// 发送弹药信息
    void sendBulletInfoMsg(BaseRole *role);

private:
    QHash<int,BaseMap*> mBaseMapList;           /**< 地图列表 */
    QMap<int,tagGradeInfo> mGradeInfoList;      /**< 玩家等级信息列表 */
    RoleManager mRoleManager;                   /**< 管理地图上所有的角色 */
    QTimer mUpdateTimer;                        /**< 更新定时器 */
    int mListenPort;                            /**< 侦听端口 */
    QHash<int,tagBulletInfo*> mBulletInfoList;  /**< 弹药信息列表 */
    chttpserver mHttpServer;                    /**< http服务器 */
    int nHttpServerPort;                        /**< http服务器端口 */
    QString mHttpServerIP;                      /**< http服务器IP */
    DBOperator m_SqliteDataProvider;            /**< 数据库操作 */
    QSize mViewSize;                            /**< 角色可视的范围 */
    QString mProName;                           /**< 当前项目名称 */
};

#endif // MAPMANAGER_H
